﻿using System;
using System.IO;

using PasswordProvider.ViewModel.Properties;
using PasswordProvider.ViewModel.Framework;
using ModelSettings = PasswordProvider.ObjectModel.Properties.Settings;
using PasswordProvider.ObjectModel;
using PasswordProvider.ViewModel.Service;

namespace PasswordProvider.ViewModel
{
    public class FileActionsViewModel : VisualViewModel
    {
        internal FileActionsViewModel()
            : base(Strings.FileActions_DisplayName, Strings.FileActions_ToolTip)
        {
        }

        #region Public Properties

        /// <summary>
        /// ActiveFilePath
        /// </summary>
        public TextEditViewModel ActiveFilePath
        {
            get
            {
                if(_activeFilePath ==null)
                {
                    _activeFilePath = new TextEditViewModel(
                        Strings.FileActions_ActiveFile_DisplayString,
                        Strings.FileActions_ActiveFile_ToolTip,
                        ModelSettings.Default.ActiveFilePath,
                        true);                    
                }
                return _activeFilePath;
            }             
        } private TextEditViewModel _activeFilePath;

        /// <summary>
        /// BackupFilePath: The backup file path
        /// </summary>
        public TextEditViewModel BackupFilePath
        {
            get
            {
                if (_backupFilePath == null)
                {
                    _backupFilePath = new TextEditViewModel(
                        Strings.FileActions_BackupFile_DisplayString,
                        Strings.FileActions_BackupFile_ToolTip,
                        ModelSettings.Default.BackupFilePath,
                        true);
                }
                return _backupFilePath;
            }
        } private TextEditViewModel _backupFilePath;

        /// <summary>
        /// ExportFilePath: The file to export to.
        /// </summary>
        public TextEditViewModel ExportFilePath
        {
            get
            {
                if (_exportFilePath == null)
                {
                    _exportFilePath = new TextEditViewModel(
                        Strings.FileActions_Export_DisplayString,
                        Strings.FileActions_Export_ToolTip,
                        null, true);
                }
                return _exportFilePath;
            }
        } private TextEditViewModel _exportFilePath;

        /// <summary>
        /// NewCommand: Create a new file.
        /// </summary>
        public CommandViewModel NewCommand
        {
            get
            {
                if (_newCommand == null)
                {
                    _newCommand = new CommandViewModel(
                        Strings.FileActions_ActiveFile_CreateNew_DisplayString,
                        Strings.FileActions_ActiveFile_CreateNew_ToolTip,
                        new RelayCommand(param => NewCommandExecuted()));
                }
                return _newCommand;
            }
        } private CommandViewModel _newCommand;

        /// <summary>
        /// SaveAsCommand: Save the file to a new lcation.
        /// </summary>
        public CommandViewModel SaveAsCommand
        {
            get
            {
                if (_saveAsCommand == null)
                {
                    _saveAsCommand = new CommandViewModel(
                        Strings.FileActions_ActiveFile_SaveAs_DisplayString,
                        Strings.FileActions_ActiveFile_SaveAs_ToolTip,
                        new RelayCommand(param => SaveAsCommandExecuted()));
                }
                return _saveAsCommand;
            }
        } private CommandViewModel _saveAsCommand;

        /// <summary>
        /// OpenCommand: Open an existing file.
        /// </summary>
        public CommandViewModel OpenCommand
        {
            get
            {
                if (_openCommand == null)
                {
                    _openCommand = new CommandViewModel(
                        Strings.FileActions_ActiveFile_Open_DisplayString,
                        Strings.FileActions_ActiveFile_Open_ToolTip,
                        new RelayCommand(param => OpenCommandExecuted()));
                }
                return _openCommand;
            }
        } private CommandViewModel _openCommand;
       
        /// <summary>
        /// BrowseBackupFileCommand: Browse for the backup file path.
        /// </summary>
        public CommandViewModel BrowseBackupFileCommand
        {
            get
            {
                if (_browseBackupFileCommand == null)
                {
                    _browseBackupFileCommand = new CommandViewModel(
                        Strings.FileActions_BackupFile_Browse_DisplayString,
                        Strings.FileActions_BackupFile_Browse_ToolTip,
                        new RelayCommand(param => BrowseBackupFileCommandExecuted()));
                }
                return _browseBackupFileCommand;
            }
        } private CommandViewModel _browseBackupFileCommand;

        /// <summary>
        /// BackupMode: Selects the file backup mode.
        /// </summary>
        public EnumSelectorViewModel FileBackupMode
        {            
            get
            {
                if (_backupMode == null)
                {                    
                    _backupMode = new EnumSelectorViewModel(
                        Strings.FileActions_BackupFile_BackupMode_DisplayString,
                        Strings.FileActions_BackupFile_BackupMode_ToolTip,
                        ModelSettings.Default.FileBackupMode);
                    _backupMode.DisplayItems.Add(
                        new EnumSelectorDisplayItemViewModel(
                            Strings.FileActions_BackupMode_EveryChange_DisplayName,
                            Strings.FileActions_BackupMode_EveryChange_ToolTip,
                            ObjectModel.FileBackupMode.BackupEveryChange));
                    _backupMode.DisplayItems.Add(
                        new EnumSelectorDisplayItemViewModel(
                            Strings.FileActions_BackupMode_Manually_DisplayName,
                            Strings.FileActions_BackupMode_Manually_ToolTip,
                            ObjectModel.FileBackupMode.NeverBackup));

                    _backupMode.EnumValueChanged +=
                        delegate
                        {
                            ModelSettings.Default.FileBackupMode = (ObjectModel.FileBackupMode)_backupMode.EnumValue;
                            ModelSettings.Default.Save();
                        };
                }
                return _backupMode;
            }
        } private EnumSelectorViewModel _backupMode;

        /// <summary>
        /// BackupNowCommand: Back up the data.
        /// </summary>
        public CommandViewModel BackupNowCommand
        {
            get
            {
                if (_backupNowCommand == null)
                {
                    _backupNowCommand = new CommandViewModel(
                        Strings.FileActions_BackupCommand_DisplayString,
                        Strings.FileActions_BackupCommand_ToolTip,
                        new RelayCommand(
                            param => BackupNowCommandExecuted(), 
                            param => BackupNowCommandCanExecute()));
                }
                return _backupNowCommand;
            }
        } private CommandViewModel _backupNowCommand;

        /// <summary>
        /// BackupNowCommand: Back up the data.
        /// </summary>
        public CommandViewModel RestoreFromBackupCommand
        {
            get
            {
                if (_restoreFromBackupCommand == null)
                {
                    _restoreFromBackupCommand = new CommandViewModel(
                        Strings.FileActions_RestoreFromBackup_DisplayString,
                        Strings.FileActions_RestoreFromBackup_ToolTip,
                        new RelayCommand(
                            param => RestoreFromBackupCommandExecuted(), 
                            param => RestoreFromBackupCommandCanExecute()));
                }
                return _restoreFromBackupCommand;
            }
        } private CommandViewModel _restoreFromBackupCommand;
        
        /// <summary>
        /// BrowseForExportFile: Select the file to export to.
        /// </summary>
        public CommandViewModel BrowseForExportFileCommand
        {
            get
            {
                if (_browseForExportFileCommand == null)
                {
                    _browseForExportFileCommand = new CommandViewModel(
                        Strings.FileActions_BrowseForExport_DisplayString,
                        Strings.FileActions_BrowseForExport_ToolTip,
                        new RelayCommand(param => BrowseForExportFileCommandExecuted()));
                }
                return _browseForExportFileCommand;
            }
        } private CommandViewModel _browseForExportFileCommand;

        /// <summary>
        /// ExportCommand: Export the data to the export file.
        /// </summary>
        public CommandViewModel ExportCommand
        {
            get
            {
                if (_exportCommand == null)
                {
                    _exportCommand = new CommandViewModel(
                        Strings.FileActions_ExportCommand_DisplayString,
                        Strings.FileActions_ExportCommand_ToolTip,
                        new RelayCommand(
                            param => ExportCommandExecuted(),
                            param => ExportCommandCanExecute()));
                }
                return _exportCommand;
            }
        } private CommandViewModel _exportCommand;



        #endregion // Public Interface

        #region Command Handlers (Private)

        private void SaveAsCommandExecuted()
        {
            string path = DialogViewService.ShowSaveFileDialog(
                Strings.FileActions_ActiveFile_SaveAs_DisplayString, null);
            if (path != null)
            {                
                PasswordProviderData.Current.Save(path);
                ModelSettings.Default.ActiveFilePath = path;
                ActiveFilePath.Text = path;
                ModelSettings.Default.Save();
            }
        }

        private static void OpenCommandExecuted()
        {
            string path = DialogViewService.ShowOpenFileDialog(
                Strings.FileActions_ActiveFile_Open_DisplayString, null);
            if (path != null)
            {
                NavigationManager.GoToEnterPasswordView(path);
            }
        }

        private static void NewCommandExecuted()
        {
            string path = DialogViewService.ShowSaveFileDialog(
                Strings.FileActions_ActiveFile_CreateNew_DisplayString, null);
            if (path != null)
            {
                NavigationManager.GoToSetPasswordView(path);
            }
        }

        private void BrowseBackupFileCommandExecuted()
        {
            string path = DialogViewService.ShowSaveFileDialog(
                Strings.FileActions_BackupFile_DisplayString, null);
            if (path != null)
            {
                BackupFilePath.Text = path;
                ModelSettings.Default.BackupFilePath = path;
                ModelSettings.Default.Save();
                BackupNowCommand.IsEnabled = true;
            }
        }

        private bool BackupNowCommandCanExecute()
        {
            return !String.IsNullOrEmpty(BackupFilePath.Text);
        }

        private void BackupNowCommandExecuted()
        {
            PasswordProviderData.Current.Backup();
            BackupNowCommand.IsEnabled = false;
        }

        private void BrowseForExportFileCommandExecuted()
        {
            string path = DialogViewService.ShowSaveFileDialog(
                Strings.FileActions_Export_DisplayString, null, ".txt", "Text Files (*.txt)|*.txt|All Files (*.*)|*.*");
            if (path != null)
            {
                ExportFilePath.Text = path;
                ExportCommand.IsEnabled = true;
            }
        }

        private bool ExportCommandCanExecute()
        {
            return !String.IsNullOrEmpty(ExportFilePath.Text);
        }

        private void ExportCommandExecuted()
        {
            string path = ExportFilePath.Text; 
            if(!Directory.Exists(Path.GetDirectoryName(path)))
                throw new InvalidOperationException("Directory does not exist.");

            string data = PasswordProviderData.Current.Sites.ToString();
            using (StreamWriter writer = new StreamWriter(path, false))
            {
                writer.Write(data);
            }
            ExportCommand.IsEnabled = false;
        }

        private bool RestoreFromBackupCommandCanExecute()
        {
            return (!String.IsNullOrEmpty(BackupFilePath.Text)) && File.Exists(BackupFilePath.Text);
        }

        private void RestoreFromBackupCommandExecuted()
        {
            bool ok = true; 

            // Warn if this will over write an existing file.
            if (File.Exists(ModelSettings.Default.ActiveFilePath))
            {
                ok = DialogViewService.ShowMessage(this, 
                        Strings.FileActions_RestoreFromBackup_WarnOverwrite,
                        Strings.FileActions_RestoreFromBackup_DisplayString,
                        System.Windows.MessageBoxButton.YesNo);
            }
            if (ok)
            {
                NavigationManager.GoToEnterPasswordView(ModelSettings.Default.BackupFilePath);
            }
        }

        #endregion // Command handlers
    }
}
